/**
 * Project: common.share-1.0-SNAPSHOT
 * 
 * File Created at 2011-8-11
 * $Id$
 * 
 * Copyright 1999-2100 Alibaba.com Corporation Limited.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * Alibaba Company. ("Confidential Information").  You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with Alibaba.com.
 */
package org.xukai.common.util.bean;

import net.sf.cglib.beans.BeanCopier;

import java.util.HashMap;
import java.util.Map;

/**
 * 
 * @Type BeanUtils
 * @Desc bean工具，拷贝属性，使用beanCopier，并对beanCopier做缓存
 * @author weirui.shenwr
 * @date 2012-6-15
 * @Version V1.0
 */
public class BeanUtils {

    private static final ThreadLocal<Map<String, BeanCopier>> tl = new ThreadLocal<Map<String, BeanCopier>>();

    /**
     * Get a BeanCopier
     * 
     * @param orig - Origin bean
     * @param dest - Destination bean
     * @return - BeanCopier
     */
    private static BeanCopier getBeanCopier(Object orig, Object dest) {
        if (orig == null || dest == null) {
            throw new IllegalArgumentException("Origin or Destination object is null.");
        }

        Map<String, BeanCopier> map = tl.get();

        if (map == null) {
            map = new HashMap<String, BeanCopier>();
            tl.set(map);
        }

        Class<?> orinClass = orig.getClass();
        Class<?> destClass = dest.getClass();

        String key = orinClass.getName() + ":" + destClass.getName();

        BeanCopier beanCopier = map.get(key);

        if (beanCopier == null) {
            beanCopier = BeanCopier.create(orinClass, destClass, false);
            map.put(key, beanCopier);
        }

        return beanCopier;
    }

    /**
     * Copy property values from the origin bean to the destination bean for all
     * cases where the property names are the same.
     * 
     * @param orig - Origin bean
     * @param dest - Destination bean
     */
    public static void copyProperties(Object orig, Object dest) {
        getBeanCopier(orig, dest).copy(orig, dest, null);
    }

    /**
     * Copy property values from the origin bean to the destination bean, which
     * is generated by the destination class, for all cases where the property
     * names are the same.
     * 
     * @param orig - Origin bean
     * @param destClass - Destination class
     * @return - Destination bean
     */
    public static <T> T copyProperties(Object orig, Class<T> destClass) {
        T dest = null;

        try {
            dest = destClass.newInstance();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        getBeanCopier(orig, dest).copy(orig, dest, null);

        return dest;
    }

}
